package com.huluobo.jetpackkotlindemo2006a.coroutine

import android.os.Bundle
import android.util.Log
import androidx.lifecycle.lifecycleScope
import com.huluobo.jetpackkotlindemo2006a.databinding.ActivityFlowBinding
import com.huluobo.jetpackkotlindemo2006a.viewbinding.BaseActivity
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.delay
import kotlinx.coroutines.flow.*
import kotlinx.coroutines.launch

/**
 * Created by lc on 2023/2/22.
 * flow:Kotlin中的数据流,可以发送多条数据,可以按照顺序发送多个值,在withContext或者async中只能发送一个值
 * 1.emit是发送的意思,必须要有collect接收
 * 2.flow是一个挂起的方法,必须要运行在协程中
 * 3.flow是数据流,但是是一个冷流,冷流:是在数据被订阅之后,发布者才会执行发射数据流的代码(类似于懒加载)
 * 4.collect是订阅,收集的意思,一个flow中必须要订阅后才能发送数据
 * 5.filter是过滤器,可以将发送的内容进行判断和过滤再被订阅者接收
 * 6.map是转化器,可以将发送的数据流转换为任意类型再进行输出
 */
class FlowActivity : BaseActivity<ActivityFlowBinding>() {
    override fun getViewBinding(): ActivityFlowBinding = ActivityFlowBinding.inflate(layoutInflater)

    private fun loadData() = flow {
        Log.i("TagA", "----------进入LoadData方法---------")
        for (i in 1..10) {
            delay(1000)
            emit(i)
        }
    }.filter {
        it % 2 == 0//添加的是判断,用于过滤发送的结果
    }

    private fun loadData2() = flow {
        Log.i("TagA", "----------进入LoadData方法---------")
        for (i in 1..10) {
            delay(1000)
            emit(i)
        }
    }.filter {
        it % 2 == 0//添加的是判断,用于过滤发送的结果
    }.map {
        it * 5 //用于转化,结果*5,转化为另一个对象
    }.flowOn(Dispatchers.IO)//指定flow运行在哪一个线程当中
        .catch { catch ->
            //捕获flow的异常
            Log.i("TagA", catch.message.toString())
        }

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)

        lifecycleScope.launch {
            loadData().collect {
                Log.i("TagA", it.toString())
            }

            loadData2().collect {
                Log.i("TagA", it.toString())
            }
        }
    }
}